package com.gopay.common.user.manager.impl;

import java.util.Calendar;
import java.util.Date;

import javax.annotation.Resource;

import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;

import com.gopay.common.constants.cust.UserInfoConstants;
import com.gopay.common.constants.trans.UserType;
import com.gopay.common.domain.UserInfo;
import com.gopay.common.domain.acps.MtPayPasswordStatus;
import com.gopay.common.domain.acps.PayPasswordStatus;
import com.gopay.common.domain.cust.CustCorpInfo;
import com.gopay.common.domain.cust.CustPersonInfo;
import com.gopay.common.domain.user.UserMtPayPwdResult;
import com.gopay.common.domain.user.UserPayPwdResult;
import com.gopay.common.user.dao.CustCorpInfoQueryDAO;
import com.gopay.common.user.dao.CustPersonInfoQueryDAO;
import com.gopay.common.user.dao.UserInfoQueryDAO;
import com.gopay.common.user.manager.UserMtPayPwdManager;
import com.gopay.common.util.DateUtils;
import com.gopay.common.util.NonrevEncr;
import com.gopay.common.util.pwd.UserPwdUtil;

/**
 * 
 * @author lizheng
 *
 */
@Service("userMtPayPwdManager")
public class UserMtPayPwdManagerImpl implements UserMtPayPwdManager {

    @Resource(name = "custCorpInfoQueryDao")
    private CustCorpInfoQueryDAO custCorpInfoQueryDao;

    @Resource(name = "custPersonInfoQueryDao")
    private CustPersonInfoQueryDAO custPersonInfoQueryDao;

    @Resource(name = "userInfoQueryDao")
    private UserInfoQueryDAO userInfoQueryDao;

    @Override
    public UserMtPayPwdResult verifyMtPayPwd(String userId, String mtPayPwd) {
        boolean verify = false;

        UserMtPayPwdResult result = new UserMtPayPwdResult(verify, 0, 0, null, null);
        if (StringUtils.isBlank(userId) || StringUtils.isBlank(mtPayPwd)) {
            result.setErrorMsg("支付密码不能为空");
            return result;
        }

        UserInfo ui = userInfoQueryDao.find(UserInfo.class, userId);
        if (ui == null) {
            result.setErrorMsg("can't find user while userId is " + userId);
            return result;
        }

        String errorMsg = "";
        String custId = ui.getCustId();
        String custType = ui.getUserType();
        
        if (UserType.Person.value.equals(custType)) {
            CustPersonInfo ci = custPersonInfoQueryDao.find(CustPersonInfo.class, custId);

            // 校验支付密码是否锁定
            if (MtPayPasswordStatus.NORMAL.ordinal() != ci.getMtPayPwdStatus()) {
                result.setMtPayPwdStatus(MtPayPasswordStatus.get(ci.getMtPayPwdStatus()));
                result.setTodayErrCount(ci.getTodayMtPwdErrNum());
                result.setTotalErrCount(ci.getTotalMtPwdErrNum());
                result.setErrorMsg("支付密码被锁定，可通过“找回支付密码”解锁，或联系客服完成支付密码解锁");
                return result;
            }
            
            // edit hougn 2017-01-05 pci认证,sha1修改为sha512  start
            StringBuilder sb=new StringBuilder(custId.trim());
            sb.append(mtPayPwd.trim());
            
            // 支付密码输入错误
            if (!UserPwdUtil.checkPwd(ci.getMtPayPwd(), sb)) {
           // edit hougn 2017-01-05 pci认证  end
                errorMsg = "支付密码输入错误，请重新输入";
                if(ci.getTodayMtPwdErrNum()<UserInfoConstants.MAX_MTPAYPWD_DAY_ERR){
                    ci.setTodayMtPwdErrNum(ci.getTodayMtPwdErrNum() + 1);
                }
                if(ci.getTodayMtPwdErrNum() == UserInfoConstants.MAX_MTPAYPWD_DAY_ERR){
                    ci.setMtPayPwdStatus(MtPayPasswordStatus.LOCK_ONEDAY.ordinal());
                    ci.setMtPayPwdLockTime(new Date());
                    errorMsg = "支付密码输错次数已达上限，支付密码被锁定。 可通过“找回支付密码”解锁，或联系客服完成支付密码解锁";
                }
                ci.setTotalMtPwdErrNum(ci.getTotalMtPwdErrNum() + 1);
                custPersonInfoQueryDao.update(ci);
            } else {
                verify = true;
                ci.setTodayMtPwdErrNum(0);
                ci.setMtPayPwdStatus(MtPayPasswordStatus.NORMAL.ordinal());
                // edit hougn 2017-01-05 pci认证,sha1修改为sha512  start
                if(UserPwdUtil.isSHA1(ci.getMtPayPwd())){
                    ci.setMtPayPwd(NonrevEncr.sha512(sb));
                }
                // edit hougn 2017-01-05 pci认证  end
                custPersonInfoQueryDao.update(ci);
            }
            return makePersonPayPwdResult(custId, custType, verify, errorMsg);
        } else {
        	result.setErrorMsg("error type while userId is " + userId);
        	return result;
        }
    }

    private UserMtPayPwdResult makePersonPayPwdResult(String custId, String userType, boolean verify, String errorMsg) {
    	UserMtPayPwdResult result = new UserMtPayPwdResult();
        CustPersonInfo ci = custPersonInfoQueryDao.find(CustPersonInfo.class, custId);
        result.setMtPayPwdStatus(MtPayPasswordStatus.get(ci.getMtPayPwdStatus()));
        result.setTodayErrCount(ci.getTodayMtPwdErrNum());
        result.setTotalErrCount(ci.getTotalMtPwdErrNum());
        result.setVerifySuccess(verify);
        result.setUserType(UserType.get(userType));
        if (StringUtils.isNotBlank(errorMsg)) {
            result.setErrorMsg(errorMsg);
        }
        return result;
    }

    private UserPayPwdResult makeCorpUserPayPwdResult(String custId, String userType, boolean verify, String errorMsg) {
        UserPayPwdResult result = new UserPayPwdResult();
        CustCorpInfo ci = custCorpInfoQueryDao.find(CustCorpInfo.class, custId);
        result.setPayPwdStatus(PayPasswordStatus.get(ci.getPayPwdStatus()));
        result.setTodayErrCount(ci.getTodayPwdErrNum());
        result.setTotalErrCount(ci.getTotalPwdErrNum());
        result.setVerifySuccess(verify);
        result.setUserType(UserType.get(userType));
        if (StringUtils.isNotBlank(errorMsg)) {
            result.setErrorMsg(errorMsg);
        }
        return result;
    }


    @Override
    public boolean updateMtPayPwd(String userId, String newPayPwd) {
        UserInfo ui = userInfoQueryDao.find(UserInfo.class, userId);
        if (ui != null) {
            String custId = ui.getCustId();
            String custType = ui.getUserType();
            StringBuilder sb=new StringBuilder(custId.trim());
            sb.append(newPayPwd.trim());
            if (UserType.Person.value.equals(custType)) {
                CustPersonInfo ci = custPersonInfoQueryDao.find(CustPersonInfo.class, custId);
                // edit hougn 2017-01-05 pci认证,sha1修改为sha512  start
                String vPayPwd = NonrevEncr.sha512(sb);
                // edit hougn 2017-01-05 pci认证  end
                ci.setPayPwd(vPayPwd);
                ci.setPayPwdStatus(PayPasswordStatus.NORMAL.ordinal());
                ci.setTodayPwdErrNum(0);
                custPersonInfoQueryDao.update(ci);
                return true;
            } else {
                CustCorpInfo ci = custCorpInfoQueryDao.find(CustCorpInfo.class, custId);
                // edit hougn 2017-01-05 pci认证,sha1修改为sha512  start
                String vPayPwd = NonrevEncr.sha512(sb);
                // edit hougn 2017-01-05 pci认证  end
                ci.setPayPwd(vPayPwd);
                ci.setPayPwdStatus(PayPasswordStatus.NORMAL.ordinal());
                ci.setTodayPwdErrNum(0);
                custCorpInfoQueryDao.update(ci);
                return true;
            }
        }
        return false;
    }



    /**
     * 校验锁定时间是否在三个小时内 如：锁定时间为10:20 当前时间为13:21 返回true
     * 
     * @param lockTime
     *            密码锁定时间
     * @return
     */
    private boolean checkTime(Date lockTime) {
        if (lockTime == null) {
            return true;
        }
        String lock = DateUtils.format(DateUtils.add(lockTime, Calendar.HOUR,
                UserInfoConstants.FIND_PAYPWD_UNAVAILABLE_TIME));
        String now = DateUtils.format(new Date());
        return Long.parseLong(now) > Long.parseLong(lock);
    }
}
